using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using ExcelConfig;
using ExcelConfig.StoreAPI;
using hub.Core.Extensions;
using hub.data;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Https;
using Microsoft.Extensions.DependencyInjection;

namespace hub.Server
{
    public class Program
    {
        const string kuyu = "kuyu";
        [RequiresUnreferencedCode("")]
        public static int Main(string[] args)
        {
            Console.OutputEncoding = Encoding.UTF8;
            if (!Directory.Exists("config")) Directory.CreateDirectory("config");
            ConfigStoreHelper.EnterConfigStoreAPIConfig();
            ExcelConfigHelper.SetDefault("配置域", "hub");
            ExcelConfigHelper.SetDefault("配置名", "hubserve");
            ExcelConfigHelper.SetDefault("用户表", "accounts");
            ExcelConfigHelper.SetDefault("令牌表", "sig");

            try
            {
                if (args?.Count(t=> t.Equals("cmd", StringComparison.OrdinalIgnoreCase)) > 0)
                {

                    Console.WriteLine("Console Mode ON.");
                    string cmd;
                    do
                    {
                        Console.Write("# ");
                        cmd = Console.ReadLine()??string.Empty;
                        switch (cmd)
                        {
                            case "https":
                                Console.Write("on/off? ");
                                var https_ison = Console.ReadLine() ?? string.Empty;
                                if (https_ison.Equals("on", StringComparison.OrdinalIgnoreCase))
                                {
                                    Console.Write("cert file: ");
                                    var certpath = Console.ReadLine() ?? string.Empty;
                                    Console.Write("cert pass: ");
                                    var certpass = Console.ReadLine() ?? string.Empty;

                                    HUB.config.WriteText("安全传输", "启用");
                                    HUB.config.WriteText("安全证书文件", certpath);
                                    HUB.config.WriteText("安全证书密码", certpass);
                                }
                                else HUB.config.WriteText("安全传输", "不启用");
                                continue;
                            case "host":
                                Console.Write("host uris: ");
                                var hosturis = Console.ReadLine();
                                if (string.IsNullOrEmpty(hosturis)) continue;
                                HUB.config.WriteText("监听地址", hosturis);
                                continue;
                            case "user":
                                Console.Write("Username: ");
                                var username = Console.ReadLine();
                                Console.Write("Password: ");
                                var userpass = Console.ReadLine();
                                HUB.config.WriteText("Account.Name", username);
                                HUB.config.WriteText("Account.Password", userpass);
                                continue;
                            case "webdomain":
                                Console.Write("WebDomain: ");
                                var webdomain = Console.ReadLine();
                                HUB.config.WriteText("域名", webdomain);
                                continue;
                            case "enableforward":
                                Console.Write("Enable Forward(Y/N): ");
                                var enableforward = Console.ReadLine()?.Equals("y", StringComparison.OrdinalIgnoreCase) ?? true;
                                HUB.config.WriteYesOrNo("开启转发", enableforward);
                                continue;
                            case "log":
                                Console.Write("Enable LOG(Y/N): ");
                                var log_on = Console.ReadLine()?.Equals("y", StringComparison.OrdinalIgnoreCase) ?? true;
                                HUB.config.WriteYesOrNo("show-log", log_on);
                                continue;
                        }
                        break;
                    } while (true);

                    return 0;
                }

                var builder = WebApplication.CreateSlimBuilder(new WebApplicationOptions
                {
                    Args = args
                });

                // in 001: 配置协议、端口、地址
                var safeHttps = HUB.config.Text("安全传输") == "启用";
                builder.WebHost.ConfigureKestrel((context, serverOptions) =>
                {
                    var hostAddr = IPAddress.Any;
                    if (safeHttps)
                    {
                        var certPath = HUB.config.Text("安全证书文件");
                        var certPass = HUB.config.Text("安全证书密码");
                        if (certPath == null || certPass == null || !File.Exists(certPath))
                        {
                            Console.WriteLine("没有配置HTTPS证书, 自动关闭安全传输。");
                            safeHttps = false;
                        }
                        else
                        {
                            var certificate = X509CertificateLoader.LoadPkcs12FromFile(certPath, certPass);
                            if (certificate == null)
                            {
                                Console.WriteLine("HTTPS证书错误, 自动关闭安全传输。");
                                safeHttps = false;
                            }
                            else
                            {
                                serverOptions.ConfigureHttpsDefaults(options =>
                                {
                                    options.ServerCertificate = certificate;
                                    options.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
                                });
                            }
                        }
                    }
                });

                builder.Services.AddCors(options =>
                {
                    options.AddPolicy(kuyu, policy =>
                    {
                        policy.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin()
                            .WithExposedHeaders("Set-Token");
                    });
                });

                builder.Services.AddFastTunnelServer();

                var app = builder.Build();
                if (HUB.config.Text("跨域请求") == "支持") app.UseCors(kuyu);
                app.UseHttpsRedirection();
                app.UseAuthentication();
                app.UseAuthorization();

                app.MapControllers();
                app.UseFastTunnelServer();
                app.MapFastTunnelServer();

                var uris = HUB.config.Text("监听地址");
                app.Run(uris);
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw;
            }
            return 0;
        }
    }
}
